package vashion.azeroth.api.core.interceptor;

import java.util.Calendar;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import vashion.azeroth.api.annotation.Auth;
import vashion.azeroth.contant.GenericErrorEnum;
import vashion.azeroth.contant.MemberErrorEnum;
import vashion.azeroth.core.manager.personal.PersonalMemberManager;
import vashion.azeroth.core.manager.personal.PersonalMemberTokenManager;
import vashion.azeroth.core.personal.pojo.PersonalMember;
import vashion.azeroth.core.personal.pojo.PersonalMemberToken;
import vashion.azeroth.core.result.ApiResult;
import vashion.azeroth.common.common.check.FormatCheck;

import com.alibaba.fastjson.JSON;

@Component
public class AuthInterceptor extends HandlerInterceptorAdapter {

	
    private static final Logger log = LoggerFactory.getLogger(AuthInterceptor.class);
    
    @Autowired
    private PersonalMemberManager memberManager;
    
    @Autowired
    private PersonalMemberTokenManager memberTokenManager;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
    	
    	if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
    		HandlerMethod method = (HandlerMethod) handler;
    		Auth auth = method.getMethodAnnotation(Auth.class);
    		if(null != auth) {
    			try {
    	    		String memberId = (String)request.getParameter("memberId");
    	    		String token = (String)request.getParameter("token");
    	    		
    	    		if(StringUtils.isBlank(memberId)) {
	    				response.setContentType(MediaType.APPLICATION_JSON_VALUE);
	                    response.getWriter().print(JSON.toJSONString(ApiResult.newErrorResult(GenericErrorEnum.NOT_EMPTY.getErrorCode(), 
	                    		"memberId" + GenericErrorEnum.NOT_EMPTY.getErrorMessage())));
	    				return false;
    	    		}
    	    		
    	    		if(!FormatCheck.isNumeric(memberId)) {
    	    			response.setContentType(MediaType.APPLICATION_JSON_VALUE);
	                    response.getWriter().print(JSON.toJSONString(ApiResult.newErrorResult(GenericErrorEnum.PARAMETER_ERROR.getErrorCode(), 
	                    		"memberId" +  GenericErrorEnum.PARAMETER_ERROR.getErrorMessage())));
	                    return false;
    	    		}
    	    		
    	    		if(StringUtils.isBlank(token)) {
    	    			response.setContentType(MediaType.APPLICATION_JSON_VALUE);
	                    response.getWriter().print(JSON.toJSONString(ApiResult.newErrorResult(GenericErrorEnum.NOT_EMPTY.getErrorCode(), 
	                    		"token" + GenericErrorEnum.NOT_EMPTY.getErrorMessage())));
	    				return false;
    	    		}
    	    		
    	    		
	    			Long mId = Long.valueOf(memberId);
    	        	
    	        	PersonalMember member = memberManager.get(mId);
    	        	if(null == member) {
    	        		response.setContentType(MediaType.APPLICATION_JSON_VALUE);
    	                response.getWriter().print(JSON.toJSONString(ApiResult.newErrorResult(GenericErrorEnum.NOT_EXIST.getErrorCode(), 
    	                		"用户" + GenericErrorEnum.NOT_EXIST.getErrorMessage())));
    	                return false;
    	        	}
    	        	
	                PersonalMemberToken memberToken = memberTokenManager.get(mId);
	        		
	        		if(null == memberToken) {
	                	response.setContentType(MediaType.APPLICATION_JSON_VALUE);
	                    response.getWriter().print(JSON.toJSONString(ApiResult.newErrorResult(GenericErrorEnum.NOT_LOGIN.getErrorCode(), 
	                    		GenericErrorEnum.NOT_LOGIN.getErrorMessage())));
	                    return false;
	        		} 
	        		if(!memberToken.getAccessToken().equals(token)) {
	        			response.setContentType(MediaType.APPLICATION_JSON_VALUE);
	                    response.getWriter().print(JSON.toJSONString(ApiResult.newErrorResult(MemberErrorEnum.ACCESS_TOKEN_ERROR.getErrorCode(), 
	                    		MemberErrorEnum.ACCESS_TOKEN_ERROR.getErrorMessage())));
	                    return false;
	        		}
	        		
	        		if(DateUtils.truncatedCompareTo(memberToken.getAccessTokenTimeOut(), new Date(), Calendar.SECOND) < 0) {
	        			response.setContentType(MediaType.APPLICATION_JSON_VALUE);
	                    response.getWriter().print(JSON.toJSONString(ApiResult.newErrorResult(MemberErrorEnum.ACCESS_TOKEN_TIME_OUT.getErrorCode(), 
	                    		MemberErrorEnum.ACCESS_TOKEN_TIME_OUT.getErrorMessage())));
	                    return false;
	        		}
    	        	
    	            return true;
    	    	} catch (Exception e) {
    	    		log.error("", e);
    			}
    	    	
    		} else {
    			return true;
    		}
    	}
    	
    	return false;
    }
}
